#include "include/ThreadPool.h"
#include <iostream>

namespace Tool
{

ThreadPool::ThreadPool(size_t maxThreads, size_t queueMaxSize)
    : m_tasks(std::make_unique<BlockQueue<std::function<void()>>>(queueMaxSize))
{
    SetMaxThreads(maxThreads);
}

ThreadPool::~ThreadPool()
{
    Stop();
}

//只使用增加线程接口，减少线程需要每个线程都有停止标志有点不简洁了
void ThreadPool::SetMaxThreads(size_t maxThreads)
{
    std::unique_lock<std::mutex> lock(m_mutex);
    if (m_workers.size() < maxThreads)
    {
        for (size_t i = m_workers.size(); i < maxThreads; ++i)
        {
            m_workers.emplace_back([this] { WorkerThread(); });
        }
    }
}

size_t ThreadPool::GetActiveThreadCount() const
{
    return m_activeThreads.load();
}

void ThreadPool::WaitAll()
{
    std::unique_lock<std::mutex> lock(m_mutex);
    m_cv.wait(lock, [this] {
        return m_tasks->IsEmpty() && m_activeThreads == 0; 
        });
}

void ThreadPool::Stop()
{
    m_stop = true;
    m_cv.notify_one();
    m_tasks->Stop();
    for (auto &worker : m_workers)
    {
        if (worker.joinable())
        {
            worker.join();
        }
    }
}

void ThreadPool::WorkerThread()
{
    while (!m_stop)
    {
        std::function<void()> task;
        task = m_tasks->Pop();
        if (m_stop)
        {
            return;
        }
        ++m_activeThreads;
        try
        {
            task();
        }
        catch (const std::exception& e)
        {
            std::cout << e.what() << std::endl;
        }
        --m_activeThreads;
        m_cv.notify_one();  // 状态变化，唤醒等待的线程 通知检查是否完成任务
    }
}

} // namespace Tool
